package com.firewolf.vue.config;

import com.firewolf.vue.security.CustomUserDetailsService;
import com.firewolf.vue.security.MyAuthenticationFailureHandler;
import com.firewolf.vue.verify.ImageCodeVerifyFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

import java.util.Arrays;

/**
 * 作者：刘兴
 * 时间:19/3/6
 **/

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {


    @Autowired
    @Qualifier("customUserDetailsService")
    private UserDetailsService userDetailsService;


    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private PersistentTokenRepository tokenRepository;

    @Autowired
    private AuthenticationSuccessHandler authenticationSuccessHandler;

    @Autowired
    private AuthenticationFailureHandler authenticationFailureHandler;

    @Autowired
    private ImageCodeVerifyFilter verifyFilter;

    @Autowired
    private AccessDeniedHandler accessDeniedHandler;

    @Override
    protected void configure(HttpSecurity http) throws Exception {

//        http.httpBasic()
//                .and()
//                .authorizeRequests().anyRequest().authenticated();

        http.
                addFilterBefore(verifyFilter, UsernamePasswordAuthenticationFilter.class)
                .formLogin()
                .loginPage("/login") //登录页面
                .loginProcessingUrl("/mylogin")
                .successHandler(authenticationSuccessHandler)
                .failureHandler(authenticationFailureHandler)
//                .successForwardUrl() //成功后的页面
//                .failureForwardUrl() //失败后的页面
//                .usernameParameter("user")
//                .passwordParameter("pwd")
                .and()
                .rememberMe() //记住我
                .tokenRepository(tokenRepository)
                .tokenValiditySeconds(30)
                .and()
                .authorizeRequests()
                .antMatchers("/login", "/login.html", "/verifycode/image").permitAll() //允许不认证就就能请求的页面
                .anyRequest().authenticated(); //其他的都需要认证

        http.exceptionHandling().accessDeniedHandler(accessDeniedHandler);
        http.csrf().disable();// 禁用跨域验证
    }


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
//        auth.userDetailsService(userDetailsService).passwordEncoder(
//                new PasswordEncoder() {
//                    @Override
//                    public String encode(CharSequence charSequence) {
//                        return charSequence.toString();
//                    }
//                    @Override
//                    public boolean matches(CharSequence charSequence, String s) {
//                        return s.equals(charSequence.toString());
//                    }
//                }
//        );
    }

    /**
     * 获取系统中的用户数据
     *
     * @return
     */
    @Bean("inMemoryUserDetailsService")
    public UserDetailsService inMemoryUserDetailsService() {
        InMemoryUserDetailsManager userDetailsManager = new InMemoryUserDetailsManager();
        userDetailsManager.createUser(new User("zhangsan", "111111", Arrays.asList(new SimpleGrantedAuthority("ROLE_ADMIN"))));
        userDetailsManager.createUser(new User("lisi", "222222", Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"))));
        return userDetailsManager;
    }

    @Bean("customUserDetailsService")
    public UserDetailsService customUserDetailsService() {
        return new CustomUserDetailsService();
    }


    @Bean
    public PersistentTokenRepository persistentTokenRepository() {
        JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
        jdbcTokenRepository.setJdbcTemplate(jdbcTemplate);
        return jdbcTokenRepository;
    }
}
